10 DEFINT A-Z:PRINT "Loading...";:STAGEW=10:STAGEH=20:SC=0:GOSUB 1100
20 DIM PW2(15),BLK(19,10),STAGE(20,11),BM(2,4):PAUSE=0
30 FOR I=0 TO 14:PW2(I)=2^I:NEXT I
39 FOR I=0 TO 18:FOR J=0 TO 9:READ BLK(I,J):NEXT J:NEXT I
40 DATA 1,2,2,3,3,0,0,0,0,0
41 DATA 2,4,1,15,0,0,0,2,2,-2
42 DATA 2,1,4,1,1,1,1,1,-2,2
43 DATA 3,2,3,2,3,1,0,4,-1,0
44 DATA 3,3,2,3,6,0,0,3,1,0
45 DATA 4,2,3,1,3,2,0,6,0,0
46 DATA 4,3,2,6,3,0,0,5,0,0
47 DATA 5,2,3,1,3,1,0,8,0,1
48 DATA 5,3,2,7,2,0,0,9,1,-1
49 DATA 5,2,3,2,3,2,0,10,-1,0
50 DATA 5,3,2,2,7,0,0,7,0,0
51 DATA 6,2,3,3,1,1,0,12,0,1
52 DATA 6,3,2,7,4,0,0,13,1,-1
53 DATA 6,2,3,2,2,3,0,14,-1,0
54 DATA 6,3,2,1,7,0,0,11,0,0
55 DATA 7,2,3,3,2,2,0,16,-1,0
56 DATA 7,3,2,4,7,0,0,17,0,0
57 DATA 7,2,3,1,1,3,0,18,0,1
58 DATA 7,3,2,7,1,0,0,15,1,-1
60 ACT=0:X=0:Y=0:BCUR=0:RANDOMIZE TIMER:BNEXT=(RND*100) MOD 19
70 KEY OFF:CLS:WIDTH 40:LOCATE ,,0
75 KEY 15,CHR$(128)+CHR$(72):KEY 16,CHR$(128)+CHR$(75):KEY 17,CHR$(128)+CHR$(77):KEY 18,CHR$(128)+CHR$(80)
76 ON KEY(11) GOSUB 262:ON KEY(12) GOSUB 260:ON KEY(13) GOSUB 261:ON KEY(14) GOSUB 263
77 ON KEY(15) GOSUB 262:ON KEY(16) GOSUB 260:ON KEY(17) GOSUB 261:ON KEY(18) GOSUB 263
78 FOR I=11 TO 18:KEY(I)ON:NEXT I
80 COLOR 9,1:LOCATE 2,15
90 PRINT CHR$(201);:FOR I=1 TO STAGEW:PRINT CHR$(205);:NEXT I:PRINT CHR$(187);
100 FOR I=1 TO STAGEH
110 LOCATE I+2,15:PRINT CHR$(186);:LOCATE I+2,26:PRINT CHR$(186);
120 NEXT I
130 LOCATE 3+STAGEH,15
140 PRINT CHR$(200);:FOR I=1 TO STAGEW:PRINT CHR$(205);:NEXT I:PRINT CHR$(188);
150 COLOR 7,0:LOCATE 3,6,0:PRINT "SCORE":LOCATE 3,30:PRINT "NEXT"
160 GOSUB 1000:TS0#=TIMER:WHILE ACT>=0:K$=INKEY$
170 IF K$=CHR$(27) THEN GOTO 240
171 IF K$="p" THEN PAUSE=NOT PAUSE:GOSUB 250
180 IF PAUSE=0 THEN ON ACT GOSUB 700,750,800,900 ELSE IF ACT<>0 THEN PAUSE=0:GOSUB 250:ACT=0
190 IF PAUSE<>0 OR (TIMER-TS0#)<DELAY THEN GOTO 210
200 GOSUB 300:GOSUB 1100:TS0#=TIMER
210 WEND
220 LOCATE 24,16:COLOR 12:PRINT "GAME  OVER";:SOUND 100,2
230 FOR I=11 TO 18:KEY(I)OFF:NEXT I:WHILE INPUT$(1)<>CHR$(27):WEND
240 SCREEN 0:COLOR 7,0:WIDTH 80:CLS:END
250 LOCATE 24,16:REM Pause handler
251 IF PAUSE<>0 THEN COLOR 14,0:PRINT "  Paused  "; ELSE PRINT STRING$(STAGEW,32);
252 RETURN
259 REM Arrow keys handlers
260 IF ACT>=0 THEN ACT=1:RETURN ELSE RETURN
261 IF ACT>=0 THEN ACT=2:RETURN ELSE RETURN
262 IF ACT>=0 THEN ACT=3:RETURN ELSE RETURN
263 IF ACT>=0 THEN ACT=4:RETURN ELSE RETURN
300 IF Y>=STAGEH-BLKH THEN HT=1 ELSE HTBM=0:HTY=Y+1:GOSUB 600
310 IF HT=0 THEN C=32:GOSUB 2000:Y=Y+1:C=219:GOTO 2000
320 SCT=0:FOR I=0 TO BLKH-1:STAGE(Y+I,0)=STAGE(Y+I,0) OR BM(0,I)
330 IF STAGE(Y+I,0)=&H3FF THEN SCT=SCT+1
340 FOR J=X+1 TO X+BLKW:IF (BM(0,I) AND PW2(STAGEW-J))<>0 THEN STAGE(Y+I,J)=BLK(BCUR,0)
350 NEXT J:NEXT I:IF SCT=0 THEN SC=SC+1:GOTO 1000
355 SOUND 500,1:SOUND 1000,1
356 YT=0:WHILE YT<STAGEH-1 AND STAGE(YT,0)=0:YT=YT+1:WEND
360 SC=SC+10*2^SCT:Y=Y+BLKH-1:Y2=Y:WHILE Y>=YT AND Y2>=YT
370 IF STAGE(Y2,0)=&H3FF THEN GOSUB 500:IF Y2<YT THEN GOTO 430
380 STAGE(Y,0)=STAGE(Y2,0)
390 FOR I=1 TO STAGEW:V=STAGE(Y2,I):STAGE(Y,I)=V:LOCATE Y+3,I+15:COLOR V
400 IF V=0 THEN PRINT " "; ELSE PRINT CHR$(219);
410 NEXT I
420 Y=Y-1:Y2=Y2-1:WEND
430 FOR I=YT TO Y:LOCATE 3+I,16:PRINT STRING$(STAGEW,32);
440 FOR J=0 TO STAGEW:STAGE(I,J)=0:NEXT J
450 NEXT I:GOTO 1000
500 REM Find non-full rows upwards
501 WHILE Y2>=0:IF STAGE(Y2,0)<>&H3FF THEN RETURN
502 Y2=Y2-1:WEND:RETURN
600 REM Hit Test
601 HT=0:FOR HTI=0 TO BLKH-1
610 IF (STAGE(HTY+HTI,0) AND BM(HTBM,HTI))<>0 THEN HT=1:RETURN
620 NEXT HTI:RETURN
700 REM Move left
701 ACT=0:IF X<1 THEN RETURN
710 FOR I=0 TO BLKH-1::BM(1,I)=BM(0,I)*2:NEXT I
720 HTBM=1:HTY=Y:GOSUB 600:IF HT=1 THEN RETURN
730 FOR I=0 TO BLKH-1:BM(0,I)=BM(1,I):NEXT I
740 C=32:GOSUB 2000:X=X-1:C=219:GOTO 2000
750 REM Move right
751 ACT=0:IF X>=STAGEW-BLKW THEN RETURN
760 FOR I=0 TO BLKH-1:BM(1,I)=BM(0,I)\2:NEXT I
770 HTBM=1:HTY=Y:GOSUB 600:IF HT=1 THEN RETURN
780 FOR I=0 TO BLKH-1:BM(0,I)=BM(1,I):NEXT I
790 C=32:GOSUB 2000:X=X+1:C=219:GOTO 2000
800 REM Rotate
801 ACT=0:BR=BLK(BCUR,7):X2=X+BLK(BCUR,8):Y2=Y+BLK(BCUR,9)
810 BLKWR=BLK(BR,1):BLKHR=BLK(BR,2)
820 IF X2<0 THEN X2=0 ELSE IF X2>=STAGEW-BLKWR THEN X2=STAGEW-BLKWR
830 IF Y2<0 THEN Y2=0 ELSE IF Y2>=STAGEH-BLKHR THEN Y2=STAGEH-BLKHR
840 PW2S=PW2(STAGEW-BLKWR-X2):FOR I=0 TO BLKHR-1:BM(1,I)=BLK(BR,3+I)*PW2S:NEXT I
850 SWAP BLKH,BLKHR:HTBM=1:HTY=Y2:GOSUB 600:IF HT=1 THEN SWAP BLKH,BLKHR:RETURN
860 FOR I=0 TO BLKH-1:BM(0,I)=BM(1,I):NEXT I
870 C=32:GOSUB 2000:BCUR=BR:BLKW=BLKWR
880 X=X2:Y=Y2:C=219:GOTO 2000
900 REM Drop Block
901 ACT=0:I=Y:YMAX=STAGEH-BLKH:HT=0:WHILE HT=0 AND I<YMAX
910 HT=0:HTBM=0:HTY=I+1:GOSUB 600:IF HT=0 THEN I=I+1
920 WEND:C=32:GOSUB 2000:Y=I:C=219:GOTO 2000
1000 REM Next block
1001 LOCATE 5,5: COLOR 7,0: PRINT SC;
1010 BCUR=BNEXT:BNEXT=(RND*100) MOD 19:COLOR BLK(BCUR,0)
1020 BLKW=BLK(BCUR,1):BLKH=BLK(BCUR,2):X=(STAGEW-BLKW)/2:Y=0
1030 FOR I=0 TO 3:BM(0,I)=BLK(BCUR,I+3)*PW2(STAGEW-BLKW-X):NEXT I
1040 HTBM=0:HTY=0:GOSUB 600:IF HT=1 THEN ACT=-1:RETURN
1050 FOR I=0 TO 3:LOCATE 5+I,30:PRINT "    ";:NEXT I:XN=14:YN=2
1051 IF BLK(BNEXT,1)<3 THEN XN=15
1060 SWAP BNEXT,BCUR:SWAP X,XN:SWAP Y,YN:C=219:GOSUB 2000
1070 SWAP BNEXT,BCUR:SWAP X,XN:SWAP Y,YN:C=219:GOTO 2000
1100 REM Determine delay by score
1101 IF SC<1000 THEN DELAY=1.2:RETURN
1102 IF SC<2000 THEN DELAY=1:RETURN
1103 IF SC<3000 THEN DELAY=0.8:RETURN
1104 IF SC<4000 THEN DELAY=0.6:RETURN
1105 IF SC<5000 THEN DELAY=0.4:RETURN
1106 IF SC<7000 THEN DELAY=0.2:RETURN
1107 DELAY=0.1:RETURN
2000 REM Draw Block
2001 COLOR BLK(BCUR,0):DX=X+16:DY=Y+3
2002 ON BCUR GOTO 2010,2020,2030,2040,2050,2060,2070,2080,2090,2100,2110,2120,2130,2140,2150,2160,2170,2180
2009 LOCATE DY,DX:PRINT STRING$(2,C);:LOCATE DY+1,DX:PRINT STRING$(2,C);:RETURN
2010 LOCATE DY,DX:PRINT STRING$(4,C);:RETURN
2020 LOCATE DY,DX:PRINT CHR$(C);:LOCATE DY+1,DX:PRINT CHR$(C);
2021 LOCATE DY+2,DX:PRINT CHR$(C);:LOCATE DY+3,DX:PRINT CHR$(C);:RETURN
2030 LOCATE DY,DX:PRINT CHR$(C);:LOCATE DY+1,DX:PRINT STRING$(2,C);
2031 LOCATE DY+2,DX+1:PRINT CHR$(C);:RETURN
2040 LOCATE DY,DX+1:PRINT STRING$(2,C);:LOCATE DY+1,DX:PRINT STRING$(2,C);:RETURN
2050 LOCATE DY,DX+1:PRINT CHR$(C);:LOCATE DY+1,DX:PRINT STRING$(2,C);
2051 LOCATE DY+2,DX:PRINT CHR$(C);:RETURN
2060 LOCATE DY,DX:PRINT STRING$(2,C);:LOCATE DY+1,DX+1:PRINT STRING$(2,C);:RETURN
2070 LOCATE DY,DX+1:PRINT CHR$(C);:LOCATE DY+1,DX:PRINT STRING$(2,C);
2071 LOCATE DY+2,DX+1:PRINT CHR$(C);:RETURN
2080 LOCATE DY,DX:PRINT STRING$(3,C);:LOCATE DY+1,DX+1:PRINT CHR$(C);:RETURN
2090 LOCATE DY,DX:PRINT CHR$(C);:LOCATE DY+1,DX:PRINT STRING$(2,C);
2091 LOCATE DY+2,DX:PRINT CHR$(C);:RETURN
2100 LOCATE DY,DX+1:PRINT CHR$(C);:LOCATE DY+1,DX:PRINT STRING$(3,C);:RETURN
2110 LOCATE DY,DX:PRINT STRING$(2,C);:LOCATE DY+1,DX+1:PRINT CHR$(C);
2111 LOCATE DY+2,DX+1:PRINT CHR$(C);:RETURN
2120 LOCATE DY,DX:PRINT STRING$(3,C);:LOCATE DY+1,DX:PRINT CHR$(C);:RETURN
2130 LOCATE DY,DX:PRINT CHR$(C);:LOCATE DY+1,DX:PRINT CHR$(C);
2131 LOCATE DY+2,DX:PRINT STRING$(2,C);:RETURN
2140 LOCATE DY,DX+2:PRINT CHR$(C);:LOCATE DY+1,DX:PRINT STRING$(3,C);:RETURN
2150 LOCATE DY,DX:PRINT STRING$(2,C);:LOCATE DY+1,DX:PRINT CHR$(C);
2151 LOCATE DY+2,DX:PRINT CHR$(C);:RETURN
2160 LOCATE DY,DX:PRINT CHR$(C);:LOCATE DY+1,DX:PRINT STRING$(3,C);:RETURN
2170 LOCATE DY,DX+1:PRINT CHR$(C);:LOCATE DY+1,DX+1:PRINT CHR$(C);
2171 LOCATE DY+2,DX:PRINT STRING$(2,C);:RETURN
2180 LOCATE DY,DX:PRINT STRING$(3,C);:LOCATE DY+1,DX+2:PRINT CHR$(C);:RETURN

